package com.lry.basic.netty.protobuf.server;

import com.lry.basic.netty.protobuf.proto.Constant;
import com.lry.basic.netty.protobuf.proto.Msg;
import com.lry.basic.netty.protobuf.proto.MsgType;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @author:刘仁有
 * @desc:
 * @email:953506233@qq.com
 * @data:2019/9/30
 */
@ChannelHandler.Sharable
public class ServerHandler extends SimpleChannelInboundHandler<Msg.Request> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Msg.Request request) throws Exception {
        System.out.println(request);
        int msgType = request.getType();
        //注册请求
        if(msgType== MsgType.REGISTER_REQ.value()){
            String username = request.getUsername();
            Msg.Request registerResp = null;
            if(Constant.ALL.equals(username)||Account.account.containsKey(username)){
                registerResp = buildRegisterResult(username,false);
            }else{
                String pwd = request.getPassword();
                Account.account.put(username,pwd);//注册的账户
                registerResp = buildRegisterResult(username,true);
            }
            ctx.writeAndFlush(registerResp);
        }
        //登录请求
        else if(msgType== MsgType.LOGIN_REQ.value()){
            String username = request.getUsername();
            String password = request.getPassword();
            Msg.Request loginResp = null;
            String accountPwd = Account.account.get(username);
            if(password.equals(accountPwd)){
                Account.channelMap.put(username,ctx);
                loginResp = buildLoginResult(true,username);
            }else {
                loginResp = buildLoginResult(false,username);
            }
            ctx.writeAndFlush(loginResp);
        }
        //发送请求
        else if(msgType== MsgType.SEND_REQ.value()){
            String username = request.getUsername();//发送者
            String receiver = request.getReceiver();//接收者
            String msg = request.getMsg();//发送消息
            //群聊 通知接收者
            if(Constant.ALL.equals(receiver)){
                Set set =  Account.channelMap.entrySet();
                Iterator it = set.iterator();
                while(it.hasNext()){
                    Map.Entry<String, ChannelHandlerContext> entry = (Map.Entry<String, ChannelHandlerContext>) it.next();
                    if(ctx!=entry.getValue()){
                        //除了自己不发，其他都发
                        Msg.Request allReceiveResp = buildReceiveResult(username,msg,entry.getKey());
                        entry.getValue().writeAndFlush(allReceiveResp);
                    }
                }
            }else{ //私聊 通知接收者
                //判断receiver是否存在
                if(!Account.account.containsKey(receiver)){
                    //通知发送者发送失败
                    Msg.Request sendFailResp = buildSendFailResult(receiver,"不存在该账户");
                    ctx.writeAndFlush(sendFailResp);
                    return;
                }
                ChannelHandlerContext channel = Account.channelMap.get(receiver);
                Msg.Request receiveResp = buildReceiveResult(username,msg,receiver);
                channel.writeAndFlush(receiveResp);
            }

            //通知发送者发送成功
            Msg.Request sendResp = buildSendResult(receiver);
            ctx.writeAndFlush(sendResp);
        }
    }

    private Msg.Request buildSendFailResult(String receiver, String failReason) {
        Msg.Request sendFailResp = Msg.Request.newBuilder().
                setType(MsgType.SEND_RESP.value())
                .setUsername("server").
                        setMsg("发送给"+receiver+"失败："+failReason).build();

        return sendFailResp;
    }

    /**
     *
     * @param username 发送者
     * @param msg 内容
     * @param receiver 接收者
     * @return
     */
    private Msg.Request buildReceiveResult(String username, String msg, String receiver) {
        Msg.Request receiveResp = Msg.Request.newBuilder().
                setType(MsgType.RECEIVE_RESP.value()) //消息类型
                .setUsername(username). //发送者
                        setMsg(msg).  //消息内容
                        setReceiver(receiver). //接收者
                        build();
        return receiveResp;
    }

    private Msg.Request buildSendResult(String receiver) {
        Msg.Request sendResp = Msg.Request.newBuilder().
                setType(MsgType.SEND_RESP.value())
                        .setUsername("server").
                        setMsg("发送给"+receiver+"成功").build();
        return sendResp;
    }

    private Msg.Request buildLoginResult(boolean isSuccess, String username){
        String msg = isSuccess?Constant.LOGIN_SUCCESS:Constant.LOGIN_FAIL;
        Msg.Request loginResp = Msg.Request.newBuilder().
                setType(MsgType.LOGIN_RESP.value())
                .setUsername("server").
                        setMsg(msg).
                        setReceiver(username).
                        build();
        return loginResp;
    }

    private Msg.Request buildRegisterResult(String username, boolean isSuccess) {
        String msg = isSuccess? Constant.REGISTER_SUCCESS:Constant.REGISTER_FAIL;
        Msg.Request registerResp = Msg.Request.newBuilder().
                setType(MsgType.REGISTER_RESP.value())
                .setUsername("server").
                        setMsg(msg).
                        setReceiver(username).
                        build();
        return registerResp;
    }
}
